<?php
use Phalcon\DI\FactoryDefault,
    Phalcon\Mvc\View,
    Phalcon\Crypt,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Mvc\Url as UrlResolver,
    Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter,
    Phalcon\Mvc\View\Engine\Volt as VoltEngine,
    Phalcon\Session\Adapter\Files as SessionAdapter,
    Phalcon\Flash\Direct as Flash;

$di = new FactoryDefault();
$di->set('config', $config);
$di->set('url', function() use ($config) {
    $url = new UrlResolver();
    $url->setBaseUri($config->application->baseUri);
    $url->setBasePath($config->application->basePath);
    return $url;
}, true);

$di->set('view', function() use ($config) {
    $view = new View();
    $view->setViewsDir($config->application->index->viewsDir);
    $view->registerEngines(array(
        '.phtml' => function($view, $di) use ($config) {
            $volt = new VoltEngine($view, $di);
            $volt->setOptions(array(
                'compiledPath' => $config->application->cacheDir,
                'compiledSeparator' => '_'
            ));
            $compiler = $volt->getCompiler();
            $compiler->addFunction('out', function($val) use($compiler) {
                return 'htmlspecialchars_decode('.$val.')';
            });
            $compiler->addFunction('formatTime', function($val) use($compiler) {
                return '\Ext\Utils::formatTime('.$val.')';
            });
            $compiler->addFunction('out2', function($val) use($compiler) {
                return '\Ext\Utils::textAreaOutput('.$val.')';
            });
            $compiler->addFunction('truncate', function($val, $pass) use($compiler) {
                $value = $compiler->expression($pass[0]['expr']);
                $start = 0;
                $end = strlen($value);
                if (isset($pass[1])) $start = $compiler->expression($pass[1]['expr']);
                if (isset($pass[2])) $end = $compiler->expression($pass[2]['expr']);
                return 'mb_substr('.$value.','.$start.','.$end.',"utf-8")';
            });
            return $volt;
        }
    ));
    return $view;
}, true);
$di->set('db', function() use ($config) {
    $eventsManager = new \Phalcon\Events\Manager();
    $logger = new \Phalcon\Logger\Adapter\File("mysql.db.log");
    $eventsManager->attach(
        "db:beforeQuery",
        function ($event, $connection) use ($logger) {
            $logger->log(
                $connection->getSQLStatement(),
                \Phalcon\Logger::INFO
            );
        }
    );
    $connection = new DbAdapter(array(
        'host' => $config->database->host,
        'username' => $config->database->username,
        'password' => $config->database->password,
        'dbname' => $config->database->dbname,
        'charset' => $config->database->charset,
        'persistent' => $config->database->persistent
    ));
    $connection->setEventsManager($eventsManager);
    return $connection;
});
$di->set('dbWrite', function () use($config ) {
    $eventsManager = new \Phalcon\Events\Manager();
    $logger = new \Phalcon\Logger\Adapter\File("mysql.dbWrite.log");
    $eventsManager->attach(
        "dbWrite:beforeQuery",
        function ($event, $connection) use ($logger) {
            $logger->log(
                $connection->getSQLStatement(),
                \Phalcon\Logger::INFO
            );
        }
    );
    $db_slave = new DbAdapter( array (
        'host' => $config->dbWrite->host,
        'username' => $config->dbWrite->username,
        'password' => $config->dbWrite->password,
        'dbname' => $config->dbWrite->dbname,
        'charset' => $config->database->charset,
        'persistent' => $config->database->persistent
    ));
    $db_slave->setEventsManager($eventsManager);
    return $db_slave;
} );
$di->set('modelsManager', function(){
    return new \Phalcon\Mvc\Model\Manager();
});
$di->set('modelsMetadata', function() use ($config) {
    return new \Phalcon\Mvc\Model\Metadata\Memory();
}, true);
$di->set('session', function() {
    $session = new SessionAdapter();
    //$session = new Phalcon\Session\Adapter\Files();
    $session->start();
    return $session;
});
$di->set('cookies', function() {
    $cookies = new \Phalcon\Http\Response\Cookies();
    $cookies->useEncryption(true);
    return $cookies;
});
$di->set('crypt', function() use ($config) {
    $crypt = new Crypt();
    $crypt->setKey($config->application->cryptSalt);
    return $crypt;
});
$di->set('dispatcher', function() {
    $dispatcher = new Dispatcher();
    $dispatcher->setDefaultNamespace('Index\Controllers');
    $dispatcher->setDefaultController('index');
    $dispatcher->setDefaultAction('index');
    return $dispatcher;
});
$di->set('router', function() {
    return include_once __DIR__.'/router.php';
});
$di->set('request', function(){
    return new \Ext\MallexRequest();
});
$frontCache = new \Phalcon\Cache\Frontend\Data(array(
    "lifetime" => 86400
));
$di->set('memcache',function() use($frontCache,$config){
    return new \Phalcon\Cache\Backend\Memcache($frontCache, array(
        'host' => $config->memcache->host,
        'port' => $config->memcache->port,
        'persistent' => false
    ));
});
$di->set('redis',function() use($frontCache,$config){
    return new \Phalcon\Cache\Backend\Redis($frontCache, array(
        'host' => $config->redis->host,
        'port' => $config->redis->port,
        'auth' => $config->redis->auth,
        'persistent' => $config->redis->persistent
    ));
});
$di->setShared('session', function () {
    $session = new \Phalcon\Session\Adapter\Files();
    $session->start();
    return $session;
});
$di->set('security', function () {
    $security = new \Phalcon\Security();
    $security->setDefaultHash('+Nodm23e9^%&*+');
    $security->setWorkFactor(12);
    return $security;
}, true);